[ORG 0xf000]

%include "oskernel/include/global.inc"

[SECTION .text]
[BITS 16]

global ap_init
ap_init:
    xchg bx, bx
    mov ax, 0
    mov ss, ax
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov si, ax

.spinlock:
    mov al, 1
.spin:
    xchg al, byte [0x7f33]
    test al, al
    jnz .spin

.enter_protected_mode:
    cli
    lgdt [0x7f2d]

    in al, 0x92
    or al, 00000010b
    out 92h, al

    mov eax, cr0
    or eax, 1
    mov cr0, eax

    jmp 0x08:protected_mode

[BITS 32]
protected_mode:
    mov ax, 0x10
    mov ds, ax
    mov ss, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    mov esp, 0x7000
    mov eax, 0x8000
    mov cr3, eax

    ; 开启物理地址扩展功能：PAE cr4.pae = 1
    mov eax, cr4
    bts eax, 5
    mov cr4, eax

    ; 设置型号专属寄存器IA32_EFER.LME，允许IA_32e模式
    mov ecx, 0x0c0000080
    rdmsr
    bts eax, 8
    wrmsr

    ; 开启分页 cr0.pg = 1（必须在做完上面两步才能开启分页，否则会出错
    mov eax, cr0
    bts eax, 31
    mov cr0, eax

    jmp 0x18:long_mode

.hlt:
    sti
    hlt
    jmp .hlt

[BITS 64]
long_mode:
    inc byte [0x7f2c]

    jmp 0x100002

.hlt:
    sti
    hlt
    jmp .hlt